package org.elanfox.intellicommunity.biz.service.core.msg.impl;

import org.elanfox.intellicommunity.biz.dto.condition.MsgSearchCondition;
import org.elanfox.intellicommunity.biz.dto.msg.MsgSaveDTO;
import org.elanfox.intellicommunity.biz.dto.msg.NodeMsgDTO;
import org.elanfox.intellicommunity.biz.entity.msg.LocationMsgPO;
import org.elanfox.intellicommunity.biz.entity.msg.NodeMsgPO;
import org.elanfox.intellicommunity.biz.repository.msg.NodeMsgRepository;
import org.elanfox.intellicommunity.biz.service.core.msg.NodeMsgService;
import org.elanfox.intellicommunity.common.constant.RedisConstant;
import org.elanfox.intellicommunity.data.base.base.SpecificationAndSort;
import org.elanfox.intellicommunity.data.base.dto.BaseSaveDTO;
import org.elanfox.intellicommunity.data.base.dto.BaseSearchDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

/**
 * @author allan
 * @version 1.0.0
 * @date 2019/12/19
 */
@Service
public class NodeMsgServiceImpl extends AbstractMsgService<NodeMsgPO, Long> implements NodeMsgService {
    private NodeMsgRepository nodeMsgRepository;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    protected NodeMsgServiceImpl(NodeMsgRepository repository) {
        super(repository);
        this.nodeMsgRepository = repository;
    }

    @Override
    public NodeMsgDTO findLastByUser(Integer userId) {
        NodeMsgDTO nodeMsgDTO = (NodeMsgDTO) redisTemplate.opsForHash().get(RedisConstant.KEY_LAST_NODE_MSG, "user_" + userId);
        if (nodeMsgDTO == null) {
            NodeMsgPO nodeMsgPO = nodeMsgRepository.findTop1ByUserIdOrderByCreateTimeDesc(userId);
            if (nodeMsgPO == null) {
                return null;
            }
            nodeMsgDTO = new NodeMsgDTO(nodeMsgPO);
        }

        return nodeMsgDTO;
    }

    @Override
    public NodeMsgPO save(LocationMsgPO locationMsgPO) {
        NodeMsgDTO lastNode = this.findLastByUser(locationMsgPO.getUserId());

        if (lastNode != null && locationMsgPO.getLocatorId().equals(lastNode.getLocatorId())) {
            //过滤掉
            return null;
        }

        NodeMsgPO nodeMsgPO = new NodeMsgPO();
        nodeMsgPO.setStationId(locationMsgPO.getStationId());
        nodeMsgPO.setLocatorId(locationMsgPO.getLocatorId());
        nodeMsgPO.setLocatorInfo(locationMsgPO.getLocatorInfo());
        nodeMsgPO.setCardId(locationMsgPO.getCardId());
        nodeMsgPO.setUserId(locationMsgPO.getUserId());
        nodeMsgPO.setRealName(locationMsgPO.getRealName());
        nodeMsgPO.setUserType(locationMsgPO.getUserType());
        nodeMsgPO = repository.save(nodeMsgPO);

        //覆盖redis
        redisTemplate.opsForHash().put(RedisConstant.KEY_LAST_NODE_MSG, "user_" + locationMsgPO.getUserId(), new NodeMsgDTO(nodeMsgPO));

        return nodeMsgPO;
    }

    @Override
    protected SpecificationAndSort<NodeMsgPO> specificationAndSort(BaseSearchDTO searchDTO) {
        MsgSearchCondition condition = (MsgSearchCondition) searchDTO;
        Specification<NodeMsgPO> specification = (root, cq, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            predicates.add(normalPredicates(condition, root, cb));

            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        return new SpecificationAndSort<>(specification, sort);
    }

    @Override
    public NodeMsgPO save(BaseSaveDTO saveDTO) {
        MsgSaveDTO msgSaveDTO = (MsgSaveDTO) saveDTO;
        NodeMsgPO nodeMsgPO = new NodeMsgPO();


        return null;
    }
}
